{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Calysto Simulator\n",
"\n",
"Requires:\n",
"\n",
"* [metakernel](https://github.com/Calysto/metakernel)\n",
"* [calysto](https://github.com/Calysto/calysto)\n",
"\n",
"Both can be installed via pip. These are already installed on Athena at Bryn Mawr College.\n",
"\n",
"For the %%brain magic, you need to use the calysto magics:\n",
"\n",
"```python\n",
"from calysto import register_ipython_magics\n",
"register_ipython_magics()\n",
"```\n",
"\n",
"These are already loaded locally on the Athena server.\n",
"\n",
"You can also program the simulator without the magic, but it requires some boiler-plate code.\n",
"\n",
"## Start the simulator\n",
"\n",
"The simulator runs in a thread and has a GUI via the IPython widgets:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from calysto.simulation import View\n",
"View(\"Bug1\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You won't be able to see the simulation view above, unless you are running a live kernel. But it would look something like this:\n",
"\n",
"\n",
"\n",
"Animated:\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Write a brain controller\n",
"\n",
"Each robot/agent also runs in a thread. You can easily create a thread (with any error messages going to the simulator above) using the %%brain magic:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%%brain\n",
"\n",
"robot.forward(4)\n",
"robot.sleep(7.5)\n",
"robot.turnLeft(4.4)\n",
"robot.forward(2)\n",
"robot.turnRight(4.4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following methods on robot are defined:\n",
"\n",
"* forward(seconds)\n",
"* backward(seconds)\n",
"* turnLeft(seconds)\n",
"* turnRight(seconds)\n",
"* sleep(seconds)\n",
"* stop()\n",
"\n",
"Senses:\n",
"\n",
"* takePicture() - returns a 256 x 128 image from agent's camera\n",
"* getIR(position) - floating point numbers indicating 0 to 1 obstacle (1 means no obstacle, less than 1 means detection, with lower meaning closer)\n",
"* stalled - Boolean indicating bumping against something\n",
"\n",
"You can define a simulation file like Bug1.py:\n",
"\n",
"```python\n",
"from calysto.simulation import LadyBug, Spider, Simulation, Color\n",
"import math\n",
"\n",
"def makeSimulation():\n",
" ladybug = LadyBug(550, 350, -math.pi/2)\n",
" spider = Spider(50, 50, 0)\n",
" def spiderBrain():\n",
" direction = 1\n",
" while simulation.is_running.is_set():\n",
" if spider.stalled:\n",
" direction = direction * -1\n",
" if direction == 1:\n",
" spider.forward(1)\n",
" else:\n",
" spider.backward(1)\n",
" spider.stop()\n",
" spider.brain = spiderBrain\n",
" simulation = Simulation(600, 400, ladybug, spider)\n",
" simulation.makeWall(500, 100, 10, 200, Color(255, 255, 0))\n",
" simulation.makeWall(10, 100, 190, 10, Color(255, 255, 0))\n",
" simulation.makeWall(300, 100, 200, 10, Color(255, 255, 0))\n",
" simulation.makeWall(100, 300, 410, 10, Color(255, 255, 0))\n",
" simulation.makeWall(10, 200, 390, 10, Color(255, 255, 0))\n",
" return simulation\n",
"```\n",
"\n",
"There are three robots types:\n",
"\n",
"* Spider\n",
"* LadyBug\n",
"* Robot - based on the Scribbler/IPRE robot\n",
"\n",
"## Implementation details\n",
"\n",
"Some effort has been taken to reduce the load on the server, and between notebook and kernel. \n",
"\n",
"* minimum update computation: computes collisions, and IR hits\n",
"* camera images taken on request (expensive)\n",
"* simulator view is transfered to notebook as SVG for efficient size and speed\n",
"* each controller/brain runs in its own thread\n",
"\n",
"### Variations\n",
"\n",
"You can use the simulator in a variety of styles, including without graphics, faster than real time, multiple controllers, etc.\n",
"\n",
"Here is an example getting an image from the LadyBug's camera:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from calysto.simulation import get_robot\n",
"from calysto.display import display"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAACACAIAAABr1yBdAAAFAklEQVR4nO3cUUslZRzH8f/YvhUv\nvPDCCwklI0MwQ0JFROUgIq6JqNdFN/+b2NewL6CLLroINtpdSkxka2OJiiUqJJaIiqjewTl2MXJ2\nzjxz1M56zjMzv++Hw+E/s4s+MzzfHVnUxMwNUDUUewFATAQAaQQAaQQAaQQAaQQAaQQAaQQAacnZ\nWcfx+fnFMDzsA18M0EeH9m94smsA7aHwZHsYGfGbWyHQi337O3cmsST8a8UnXzCAbkP6PjrqV6wd\nuIY9+yt7mNvK4c4uSwC5w+z72JiHq4GyXfuzPV++xesQQO49HcbHPVwi6mfHfm/P7X2Z3aCiAYSH\nExMeLhrVsm2/pcPle50ACg5z89SUh9eAstmyX9Mh3XPhFieAHgPIHU5Pe3hJGLxNe5YOhTueAPoV\nQPs1M+PhtaHfNuyX6+x4Auh7AO1Xq2Vzcx5eJ25Kw84ss7MJoHiIGEB7np/38ILRm3X7ObubCeCK\noQwBpHOrZYuLHl45rmPVfizc6wRwxVCqANL35WUPrx/drNgP6f4mgJoEkL63Wra25uGNQGrZnmY3\nNwEUn6x0AOnQaHh4O5Qt2ffhjieA4pM1CCB9bW56eFPULNi32e1OAB1D4cnaBNBsWqtlt297eGsU\nvGXf5La+WgD8RJiZ2d27HnsJEczbk9hLiI8nwPOh2bSDA+/hJlbOm/Z1+o/3kA3xBICWN+yr2Eso\nEQLQMmtfxl5CudyKvYCyu3Ppb88ueKZezzsD/6XcM3aaWMI/eTkE0OHy7V5dr9sJW78QN6X+XrPj\n2EsoLwKI471BPWpetaPBfKKKIoA6e8U+i72EsiOA2pq0h7GXUAEEAGn8L1A0L9unffrI53aeWGL2\nUp8+fp3wBIA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0\nAoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0\nAoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoC0W7EX\noOuxP+7rx5/0yb5+/HrgCQBpBFBbj/xR7CVUAAHU2amfxl5C2RFAHO/7gD7RiZ8M6DNVEwHU37Ef\nx15CefG/QB3e9fyZO8GZKjryoxmfib2KMkrOzjqOz8/zQ+HJK4fCw0veux2Gc3iYfbVa+Tn3nh1a\nLWs2nw/Nph3808tNrJBZn00sGbKhxJLskHuZWeFhOmTfs4e5P+12mB2uPNnDYeGZbif5EkjLA38Q\newnlQgBy7vv92EsoEb4Euhje/qOX21dp8z7Pl0A8AcxMcfeb2T2/F3sJ8ak/ATaf9XDT6mbBF2Sf\nALoBNDovHEu+RAASAaz9FN4HXFj2ZQLoGApPVjGA5afh5aOrFV8hgK4nqxXA4nfhheNaVn2VAKoa\nwPyT8HrRo3VfJ4BqBDDX3x+0UtfwhhFA2QKY4fveY9jwDQIoHgYTwPQX4RUhgk3fTAcC6G8AU5+H\nl4DS2fKtdCCAFw1ggm9erL5t304HAuj6ng7jn4QrRA3t+E57Fg1g7ONwMZC267vtuSYBjH4Ufkbg\nf9vzvexhiQIY+bD7qoGB2Pf93JkbCGD4gxtZG1AWh34YnkzMB74QoDT4iTBIIwBIIwBIIwBIIwBI\nIwBIIwBI+w+w+51wyvco0wAAAABJRU5ErkJggg==\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"with get_robot() as robot:\n",
" display(robot.takePicture())"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}